home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Applications / Utilities / BackSpace / Source / ThinkMore.m < prev    next >
Text File  |  1993-07-14  |  10KB  |  435 lines

  1. //  ThinkMore.m
  2. //
  3. //  Contains additional methods used in the Thinker class.
  4. //
  5. //  You may freely copy, distribute, and reuse the code in this example.
  6. //  NeXT disclaims any warranty of any kind, expressed or  implied, as to its
  7. //  fitness for any particular use.
  8.  
  9. #import "Thinker.h"
  10. #import "SpaceView.h"
  11. #import "BackView.h"
  12. #import "SleepView.h"
  13. #import "BlackView.h"
  14. #import "Password.h"
  15. #import "psfuncts.h"
  16.  
  17.  
  18. #import <appkit/appkit.h>
  19. #import <objc/NXBundle.h>
  20.  
  21.  
  22. #define VIEWDIRECTORY    "/LocalLibrary/BackSpaceViews"
  23.  
  24. static char *compiledViewNames[] = {
  25.     "Space",
  26.     "Boink",
  27.     "Black",
  28.     };
  29.  
  30. #define COMVIEWCOUNT    (sizeof(compiledViewNames)/sizeof(*compiledViewNames))
  31.  
  32. @implementation Thinker(thinkMore)
  33.  
  34.  
  35. //must invoke this before creating window or setting up the views
  36. - getViewType
  37. {
  38.     int i;
  39.     id theMatrix;
  40.     char buf[MAXPATHLEN];
  41.     ModuleInfo *m;
  42.  
  43.     strcpy( buf, NXHomeDirectory());
  44.     strcat( buf, "/Library/BackSpaceViews");
  45.  
  46.     moduleList = [[ModuleList alloc] init];
  47.  
  48.     [self loadViewsFrom:buf];
  49.     [self loadViewsFrom: [self appDirectory]];
  50.     [self loadViewsFrom: VIEWDIRECTORY];
  51.  
  52.     for (i = 0; i < COMVIEWCOUNT; i++)
  53.     {
  54.         m = [[ModuleInfo alloc] 
  55.             initWithView:nil name:compiledViewNames[i] path:NULL];
  56.         [moduleList addObject: m];
  57.     }
  58.  
  59.     [moduleList sort];
  60.     [viewSelectionBrowser loadColumnZero];
  61.     theMatrix = [viewSelectionBrowser matrixInColumn:0];
  62.     [theMatrix selectCellAt:realViewIndex :0];
  63.     [theMatrix scrollCellToVisible:realViewIndex :0];
  64.  
  65.     return self;
  66. }
  67.  
  68.  
  69. - selectRealViewIndex:sender
  70. {
  71.     //sender is the NXBrowser
  72.     int index = [[viewSelectionBrowser matrixInColumn:0] selectedRow];
  73.  
  74.     if (index == realViewIndex) return self;
  75.     if (index == -1)
  76.     {
  77.         id theMatrix = [viewSelectionBrowser matrixInColumn:0];
  78.         [theMatrix selectCellAt:realViewIndex :0];
  79.         [theMatrix scrollCellToVisible:realViewIndex :0];
  80.         return self;
  81.     }
  82.     
  83.     realViewIndex = index;
  84.     [self setVirtualViewIndexAndIncrement:NO];
  85.     
  86.     return self;
  87. }
  88.  
  89.  
  90. // this method is the actual view setting mechanism,
  91. // guaranteed to get called to set the view
  92.  
  93. - setVirtualViewIndexAndIncrement:(BOOL)flag
  94. {
  95.     id myView;
  96.     id newInspector;
  97.     
  98.     if (realViewIndex)
  99.     {
  100.         virtualViewIndex = realViewIndex-1;
  101.         [self selectScreenSaverViews];
  102.     }
  103.  
  104.     else
  105.     {
  106.         if (flag)
  107.         {
  108.             virtualViewIndex = random() % [moduleList count];
  109.             [self selectScreenSaverViews];
  110.             myView = [self backView];
  111.             
  112.             while ([myView respondsTo:@selector(isBoringScreenSaver)]
  113.                 && [myView isBoringScreenSaver])
  114.             {
  115.                 if (++virtualViewIndex >= [moduleList count])
  116.                     virtualViewIndex = 0;
  117.  
  118.                 [self selectScreenSaverViews];
  119.                 myView = [self backView];
  120.             }
  121.         }
  122.         else [self selectScreenSaverViews];
  123.     }
  124.  
  125.  
  126.     //---------------------------------------------
  127.     // now plug in the inspector
  128.     //---------------------------------------------
  129.     myView = [self backView];
  130.  
  131.     if ([myView respondsTo:@selector(inspector:)])
  132.     {
  133.         newInspector = [myView inspector:self];
  134.         if (!newInspector) newInspector = [self nullInspector];
  135.     }
  136.     else newInspector = [self nullInspector];
  137.     
  138.     if (newInspector != currentInspector)
  139.     {
  140.         if ([oldInspectorOwner respondsTo:@selector(inspectorWillBeRemoved)])
  141.             [oldInspectorOwner inspectorWillBeRemoved];
  142.         // either myView will be the inspector owner, or it won't care
  143.         oldInspectorOwner = myView;
  144.         
  145.         // don't want it to resize the box.  Suboptimal technique...
  146.         [newInspector setFrame:&inspectorFrame];
  147.  
  148.         [invisibleInspectorBox setContentView: newInspector];
  149.         currentInspector = newInspector;
  150.  
  151.         if ([myView respondsTo:@selector(inspectorInstalled)])
  152.             [myView inspectorInstalled];
  153.  
  154.         [invisibleInspectorBox display];
  155.     }
  156.  
  157.     return self;
  158. }
  159.  
  160.  
  161. - selectScreenSaverViews
  162. {
  163.     id theView, bigWindow;
  164.     int myBacking;
  165.  
  166.     //need to order out big window if that's the type and buffering changed
  167.     
  168.     theView = [self backView];
  169.  
  170.     myBacking = [self backingTypeForView:theView];
  171.  
  172.     [self createBigWindowIfNecessaryForView:theView];
  173.  
  174.     if (myBacking == NX_BUFFERED) bigWindow = bigBufferedWindow;
  175.     else bigWindow = bigUnbufferedWindow;
  176.  
  177.     if (windowType == BACKWINDOW)
  178.     {
  179.         if (spaceWindow != bigWindow)
  180.         {
  181.             [spaceWindow orderOut:self];
  182.             [self useBackWindow:globalTier];
  183.         }
  184.     }
  185.  
  186.     spaceView = theView;
  187.     [self installSpaceViewIntoWindow:spaceWindow];
  188.  
  189.     if ([spaceView respondsTo:@selector(setImage:)])
  190.         [spaceView setImage: image];
  191.     if ([spaceView respondsTo:@selector(newWindow)]) [spaceView newWindow];
  192.  
  193.     [self setWindowTitle];
  194.  
  195.     NXWriteDefault([NXApp appName], "viewType", (realViewIndex ? 
  196.             ([moduleList nameAt: realViewIndex-1]) : "All"));
  197.  
  198.  
  199.     if (windowType) 
  200.     {
  201.         // the unbuffered window looks better if you just display
  202.         // its contents, but for a buffered oneshot window, you must
  203.         // display the window to make sure the window server window exists.
  204.  
  205.         if (myBacking == NX_BUFFERED) 
  206.             [spaceWindow display];
  207.         else 
  208.         {
  209.             [spaceView fillBoundsWithBlack];
  210.             [spaceView display];
  211.         }
  212.     }
  213.  
  214.     if (normalWindow && (windowType == NORMALWINDOW))
  215.     {
  216.         if (myBacking == NX_BUFFERED)
  217.             [normalWindow setBackingType:NX_BUFFERED];
  218.         else[normalWindow setBackingType:NX_RETAINED];
  219.     }
  220.  
  221.     return self;
  222. }
  223.  
  224. - setWindowTitle
  225. {
  226.     if ([spaceView respondsTo:@selector(windowTitle)])
  227.     {
  228.         [normalWindow setTitle: NXLocalString([spaceView windowTitle],0,0)];
  229.     }
  230.     else [normalWindow setTitle: NXLocalString("BackSpace",0,0)];
  231.     return self;
  232. }
  233.  
  234.  
  235. - getScreenLockerSetting
  236. {
  237.     const char *ptr;
  238.     
  239.     [screenLocker setState:0];
  240.     
  241.     ptr = NXGetDefaultValue([NXApp appName], "screenLocker");
  242.  
  243.     if (!ptr || !strcmp(ptr,"Off")) [self setScreenLocker:NO andRemember:NO];
  244.     else [self setScreenLocker:YES andRemember:NO];
  245.     
  246.     return self;
  247. }
  248.  
  249. - changeScreenLockerSetting:sender
  250. {
  251.     if (![password checkPassword:
  252.         NXLocalString("Enter password to change screen lock setting:",0,0)
  253.         randomPos:NO checkLock:NO withView:nil])
  254.     {
  255.         [screenLocker setState:[password isLocked]];
  256.         return self;
  257.     }
  258.  
  259.     if (![password validPassword] && ![password setPassword:self])
  260.     {
  261.         [screenLocker setState:[password isLocked]];
  262.         return self;
  263.     }
  264.     
  265.     [self setScreenLocker:([screenLocker state])andRemember:YES];
  266.     return self;
  267. }
  268.  
  269. - setScreenLocker:(BOOL)val andRemember:(BOOL)rem
  270. {
  271.     [screenLocker setState:val];
  272.     [password setLock: val];
  273.  
  274.     if (rem)
  275.     {    
  276.         if (val) NXWriteDefault([NXApp appName], "screenLocker", "On");
  277.         else NXRemoveDefault([NXApp appName], "screenLocker");
  278.     }
  279.     
  280.     return self;
  281. }
  282.  
  283.  
  284.  
  285.  
  286. //---------------------------------------------------
  287. //            View manager routines    
  288. //---------------------------------------------------
  289.  
  290. - backView
  291. {
  292.     NXRect aFrame = {{0,0},{200,200}};
  293.     id theView;
  294.     
  295.     if (![moduleList viewAt:virtualViewIndex])
  296.     {
  297.         char path[MAXPATHLEN];
  298.         id myClass;
  299.         const char *name;
  300.         char *filenames[] = {path, NULL};
  301.         ModuleInfo *mp;
  302.         struct mach_header *header;
  303.  
  304.         mp = [moduleList objectAt: virtualViewIndex];
  305.         name = [mp viewName];
  306.  
  307.         // before I loaded all classes at launch time; now classes are
  308.         // loaded only as needed.  This idea and some of the code here is
  309.         // from bill bumgarner, thanx!
  310.  
  311.         if ([mp path])    // we have path but no instance, must load class
  312.         {
  313.             long ret;
  314.             do
  315.             {
  316.                 sprintf(path, "%s/%sView.BackO", [mp path], name);
  317.                 ret = objc_loadModules(filenames, NULL, NULL, &header, NULL);
  318.  
  319.                 // objc_loadModules succeeds with a warning if the architecture of the
  320.                 // object file is wrong, so we better check if we really got a class
  321.  
  322.                 if (!ret)    // load succeeded or was wrong architecture
  323.                 {
  324.                     sprintf(path,"%sView", name);
  325.                     myClass = objc_getClass(path);
  326.                     if (!myClass) ret = -1;
  327.                 }
  328.  
  329.             } while (ret && [mp useNextPath]);
  330.  
  331.             [mp discardAltPaths];
  332.  
  333.             if (ret)
  334.             {
  335.                 // Ugh, failed.  Will instantiate a BlackView instead...
  336.                 NXRunAlertPanel([NXApp appName], NXLocalString(
  337.                     "Could not dynamically load class: %sView",0,0),
  338.                     NULL, NULL, NULL, name);
  339.                 name = "Black";
  340.             }
  341.             else
  342.             {
  343.                 [mp setHeader:header];
  344.             }
  345.         }
  346.  
  347.         //at this point we must have a valid name for a loaded class
  348.         
  349.         sprintf(path,"%sView", name);
  350.         myClass = objc_getClass(path);
  351.  
  352.         theView = [[myClass allocFromZone:backZone] initFrame:&aFrame];
  353.         [[moduleList objectAt:virtualViewIndex] setView:theView];
  354.     }
  355.  
  356.     theView = [moduleList viewAt:virtualViewIndex];
  357.     
  358.     return theView;
  359. }
  360.  
  361. - showInfoPanel:sender
  362. {
  363.     if (!infoPanel)
  364.     {
  365.         if (![NXApp loadNibSection:"Info.nib" owner:self withNames:NO fromZone:[self zone]])
  366.             NXLogError ("Can't find Info.nib!");    
  367.     }
  368.     [infoPanel makeKeyAndOrderFront:sender];
  369.     return self;
  370. }
  371.  
  372. #define SLEEPSIZE (3.0)
  373.  
  374. - createSleepWindow
  375. {
  376.     if (!sleepWindow)
  377.     {
  378.         NXRect sleep={{0, 0},{SLEEPSIZE, SLEEPSIZE}};
  379.         id aView = [[SleepView alloc] initFrame:&sleep];
  380.  
  381.         sleepWindow = [[Window alloc]
  382.             initContent:&sleep style:NX_TOKENSTYLE
  383.             backing:NX_NONRETAINED buttonMask:0 defer:NO];
  384.  
  385.         [sleepWindow setEventMask:(NX_MOUSEENTEREDMASK | NX_MOUSEEXITEDMASK)];
  386.         PSsetwindowlevel(SLEEPTIER, [sleepWindow windowNum]);
  387.         PSWmakeWindowGray([sleepWindow windowNum]);
  388.         [[sleepWindow setContentView: aView] free];
  389.  
  390.         [sleepWindow setTrackingRect:&sleep inside:YES owner:aView
  391.             tag:3 left:NO right:NO];
  392.     }
  393.  
  394.     return self;
  395. }
  396.  
  397. - setSleepCorner:(int)val
  398. {
  399.     NXRect screen={{0, 0}};
  400.     NXCoord x = 0.0, y = 0.0;
  401.  
  402.     if (val)
  403.     {
  404.         [NXApp getScreenSize:&(screen.size)];
  405.         [self createSleepWindow];
  406.         if (val == 2 || val == 3) x = screen.size.width - SLEEPSIZE;
  407.         if (val == 3 || val == 4) y = screen.size.height - SLEEPSIZE;
  408.         [sleepWindow moveTo:x :y];
  409.         [sleepWindow orderFront:self];
  410.     }
  411.     else [sleepWindow orderOut:self];
  412.     return self;
  413. }
  414.  
  415. - getHotCornerSetting
  416. {
  417.     const char *ptr;
  418.     int tval, val=0;
  419.     
  420.     ptr = NXGetDefaultValue([NXApp appName], "hotCorner");
  421.     if (ptr)
  422.     {
  423.         sscanf(ptr,"%d",&tval);
  424.         if (tval >= 0 && tval <= 4) val = tval;
  425.     }
  426.     
  427.     [cornerView setState:val];
  428.     [self setSleepCorner:val];
  429.  
  430.     return self;
  431. }
  432.  
  433.  
  434. @end
  435.